package com.koi.common.utils.file;

import com.koi.common.ex.koi.YUtil;
import com.koi.common.utils.uuid.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ･ᴗ･
 * @description [UploadUtil]
 */
@Slf4j
public class UploadUtil {

    /**
     * @param multipartFile 需要上传的文件
     * @param basePath      上传配置环境路径
     * @param figure        前端配置不超过多少MB
     * @description [上传单个文件]
     * @author ･ᴗ･
     */
    public static Map<String, Object> koiSingleFile(MultipartFile multipartFile, String basePath, Integer figure) {
        Map<String, Object> map = new HashMap<>();
        long size = multipartFile.getSize();
        if (size > figure * 1048576) {
            YUtil.isTrue("上传文件必须小于" + figure + "MB");
        }
        LocalDateTime nowDateTime = LocalDateTime.now();
        // 当前日期格式
        DateTimeFormatter fileFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        // 获取文件大小
        String fileSize = FileTypeUtil.getFileSize(multipartFile);
        log.info("文件大小fileSize：{}", fileSize);
        // 文件日期路径
        String fileDatePath = nowDateTime.format(fileFormatter) + "/";
        log.info("文件日期路径：{}", fileDatePath);
        // 文件上传路径
        String fileUploadPath = basePath + fileDatePath;
        // 获取绝对路径
        File fl = new File(fileUploadPath);
        // 如果不存在，直接创建
        if (!fl.exists()) {
            fl.mkdirs();
        }
        // 获取原文件名称
        String originalFilename = multipartFile.getOriginalFilename();
        log.info("获取原文件完整名称fileName：{}", originalFilename);
        YUtil.isTrue(StringUtils.isBlank(originalFilename), "获取不到源文件名称，请刷新重试");
        // String fileName = FileTypeUtil.getFileName(originalFilename);
        // log.info("上传文件名字：{}",fileName);
        // 文件后缀[不含(.)]
        String suffixName = FileTypeUtil.getFileType(originalFilename);
        log.info("上传文件后缀suffixName：{}", suffixName);
        // 当前日期格式
        DateTimeFormatter formatterTemplate = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        // 使用UUID生成新文件名
        String newName = nowDateTime.format(formatterTemplate) + "-" + UUIDUtil.getUUIDValue(6) + "." + suffixName;
        log.info("上传文件新名字newName：{}", newName);
        // 拼接的文件绝对路径
        String absoluteFilePath = fileUploadPath + newName;
        log.info("拼接的文件绝对路径filePath：{}", absoluteFilePath);
        File file = new File(absoluteFilePath);
        // 上传文件
        try {
            // 将临时文件复制到指定位置
            multipartFile.transferTo(file);
        } catch (IllegalStateException | IOException e) {
            log.error("上传文件异常信息：{}", e.getMessage());
        }
        map.put("fileSize", fileSize); // 文件大小
        map.put("fileName", originalFilename); // 原文件名字
        map.put("suffixName", suffixName); // 文件后缀
        int index = fileUploadPath.indexOf(":");
        String fileUploadPathString = fileUploadPath.substring(index + 1) + newName;
        // 文件上传路径
        log.info("文件上传路径fileUploadPath：{}", fileUploadPathString);
        map.put("fileUploadPath", fileUploadPathString); // 文件上传路径
        map.put("newName", newName); // 新文件名字
        map.put("filePath", absoluteFilePath); // 绝对文件路径
        return map;
    }

    /**
     * @description [预览图片]
     * @author ･ᴗ･
     */
    public static void previewPicture(String url, HttpServletResponse response) {
        // 获取图片的当前路径，通过输入流读取文件内容。
        FileInputStream fis = null;
        // 输出流，通过输出流将文件返回给浏览器，在浏览器进行图片展示。
        ServletOutputStream os = null;
        try {
            fis = new FileInputStream(url);
            os = response.getOutputStream();
            // 提高读写的速度
            byte[] b = new byte[1024];
            // 边读边写
            while (fis.read(b) != -1) {
                os.write(b);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @description [文件下载]
     * @author ･ᴗ･
     */
    public static void downLoad(String filePath, HttpServletRequest request, HttpServletResponse response) {
        // 设置文件的MiMe类型
        response.setContentType(request.getSession().getServletContext().getMimeType(filePath));
        // 设置content-disposition
        response.setHeader("Content-Disposition", "attachment;filename=" + filePath);
        // 读取目标文件，通过response将目标文件写到客户
        try {
            // 读取文件
            InputStream in = new FileInputStream(filePath);
            OutputStream out = response.getOutputStream();
            //写文件
            byte[] b = new byte[1024];
            while (in.read(b) != -1) {
                out.write(b);
            }
            in.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
